﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// using pour ouverture fichier 
using System.IO;
// using pour demarrge de arduino
using System.Diagnostics;
using System.Windows.Forms;

namespace TinyPG
{
    public class generation
    {
        RichTextBox test;
        public void generer(string chaine, string proc, string CPU_Speed, RichTextBox text)
        {
            test = text;
            test.Text = "";
            //========================================création du fichier===========================================
            //++++++spécification du repertoire courant++++++

            File.Delete("prog.cpp");
            File.Delete("prog.cpp.o");
            File.Delete("prog.elf");
            File.Delete("prog.hex");
            // ++++++Création du fichier dans le repertoire courant
            StreamWriter sw = File.CreateText(@"prog.cpp");

            sw.Write(chaine);
            
            //+++++fermeture et enregistrement du fichier +++++
            sw.Close();
            //======================================== fin de création du fichier==================================


            //==================================lancement de arduino avec en param le fichier .ino=================
            

            string fullpathavr;
            if (File.Exists("avrPath.cfg"))
            {
                fullpathavr = File.ReadAllText("avrPath.cfg");
                if (!File.Exists(fullpathavr + @"\bin\avr-gcc.exe")){
                    File.Delete("avrPath.cfg");
                    test.Text += "False path in avrPath.cfg relaunch!";
                    return;
                }
            }
            else
            {
                FolderBrowserDialog folderDial = new FolderBrowserDialog();
                if (folderDial.ShowDialog() == DialogResult.OK)
                {
                    fullpathavr = folderDial.SelectedPath;
                    if (File.Exists(fullpathavr + @"\bin\avr-gcc.exe"))
                    {
                        StreamWriter pathWriter = File.CreateText(@"avrPath.cfg");
                        pathWriter.Write(fullpathavr);
                        pathWriter.Close();
                    }
                    else
                    {
                        test.Text += "False path";
                        return;
                    }
                }
                else{

                    test.Text += "Avr introuvable";
                    return;
                    }
            }


            string pathavrgcc = fullpathavr + @"\bin\avr-gcc.exe";
            string pathavrobjcopy = fullpathavr + @"\bin\avr-objcopy.exe";
            string pathavrdude = fullpathavr + @"\bin\avrdude.exe";
            string pathavrdudeconf = fullpathavr + @"\etc\avrdude.conf";

            string ret;
            // Compilation
            ret = execute(pathavrgcc, @" -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DUSB_VID=null -DUSB_PID=null prog.cpp -o prog.cpp.o ");
            test.Text += "// COMPILE // \r\n" + ret;
            test.Invalidate();
            if (!ret.Equals(""))
                return;

            //Linker
            ret =  execute(pathavrgcc, @" -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DUSB_VID=null -DUSB_PID=null prog.cpp.o -o  prog.elf ");
            test.Text += "// LINKER // \r\n" + ret;
            test.Invalidate();
            if (!ret.Equals(""))
                return;

            // TO HEX 
            ret =  execute(pathavrobjcopy, @" -O ihex prog.elf prog.hex");
            test.Text += "// TO HEX // \r\n" + ret;
            test.Invalidate();
            if (!ret.Equals(""))
                return;

            // COPY to ARDUINO 
            test.Text += "// Dude // \r\n" + execute(pathavrdude, " -p m328p -c arduino -C " + "\"" + pathavrdudeconf + "\"" + " -b 115200 -P COM3 -U flash:w:prog.hex");
            
            //======================================== fin de programmation ino ===================================

            File.Delete("prog.cpp");
            File.Delete("prog.cpp.o");
            File.Delete("prog.elf");
            File.Delete("prog.hex");
            return ;
        }

        private string execute(string filename, string arguments)
        {
            ProcessStartInfo procStartInfo = new ProcessStartInfo(filename, arguments);
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.RedirectStandardError = true;
            procStartInfo.UseShellExecute = false;
            procStartInfo.CreateNoWindow = true;

            Process process = new System.Diagnostics.Process();
            process.StartInfo = procStartInfo;
            process.Start();
            process.WaitForExit();
            string result = process.StandardOutput.ReadToEnd();
            result += process.StandardError.ReadToEnd();

            return result;
        }
    }
}
